/**
 * 所有版权归 广西梧州 陈锦韬 所有
 *
 * @Title: RxBaseSpringApplication
 * @Package com.rx.core.base
 * @Description: 启动入口
 * @author: 陈锦韬
 * @date: 2020\8\10 0010
 * @version V1.0
 * @Copyright: 2020 陈锦韬  All rights reserved.
 */
package com.rx.core.base;

import com.rx.core.anno.RxSpringBootApplication;
import com.rx.core.util.EmptyChecker;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;

/**
 * @author: Administrator
 * @Description: 启动入口 统一处理
 * @date: 2020\8\10 0010
 */
@Slf4j
public class RxBaseSpringApplication extends SpringApplication {

    public static Class<?> primarySource;
    public static ComponentScan componentScan;
    public static String[] basePackages;

    private static void setDefaultPackage(RxSpringBootApplication rxSpringBootApplication){
        //获取 foo 这个代理实例所持有的 InvocationHandler
        InvocationHandler h = Proxy.getInvocationHandler(rxSpringBootApplication);
        // 获取 AnnotationInvocationHandler 的 memberValues 字段
        Field hField = null;
        try {
            hField = h.getClass().getDeclaredField("memberValues");
            // 因为这个字段事 private final 修饰，所以要打开权限
            hField.setAccessible(true);
            // 获取 memberValues
            Map memberValues = (Map) hField.get(h);
            // 修改 value 属性值
            String[] values = (String[])memberValues.get("componentPackages");
            String[] newValues = new String[values.length + 4];
            System.arraycopy(values,0,newValues,0,values.length);
            newValues[values.length] = "com.rx.core.*";
            newValues[values.length + 1] = "com.rx.controller**";
            newValues[values.length + 2] = "com.rx.service**";
            newValues[values.length + 3] = "com.rx.hystrix**";
            memberValues.put("componentPackages", newValues);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            log.error("设置默认扫描目录失败:" + e);
        }

    }

    public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
        RxBaseSpringApplication.primarySource = primarySource;
        RxBaseSpringApplication.componentScan = primarySource.getAnnotation(ComponentScan.class);
        if(EmptyChecker.isEmpty(RxBaseSpringApplication.componentScan)){
            RxSpringBootApplication rxSpringBootApplication = primarySource.getAnnotation(RxSpringBootApplication.class);
            if(EmptyChecker.notEmpty(rxSpringBootApplication)){
                setDefaultPackage(rxSpringBootApplication);
                basePackages = rxSpringBootApplication.componentPackages();
            }
        }
        ConfigurableApplicationContext context = SpringApplication.run(primarySource, args);
        return context;
    }
}
